﻿using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class MusicPlayer : MonoBehaviour
{
    private MusicPlayer() { }
    const string SAVE_KEY = "MUSIC_SAVE_KEY";
    static List<MusicPlayer> musicPlayers = new List<MusicPlayer>();
    AudioSource player = null;
    AudioClip[] currClips;
    bool isPlayAfterMusicOff;
    float stopAtTime;
    int currClipIndex;
    bool currRandomBegin, currRandomNext;
    float currNextDelay;

    /// <summary>
    /// 读取或设置MusicPlayer播放的音频的开关
    /// </summary>
    public static bool IsMusicOn
    {
        get { return PlayerPrefs.GetInt(SAVE_KEY, 1) == 1; }
        set
        {
            PlayerPrefs.SetInt(SAVE_KEY, value ? 1 : 0);
            for (int i = 0; i < musicPlayers.Count; i++)
            {
                MusicPlayer musicPlayer = musicPlayers[i];
                if (musicPlayer.player)
                {
                    if (!value)
                    {
                        musicPlayer.stopAtTime = musicPlayer.player.time;
                        musicPlayer.player.enabled = value;//先获取时间再停
                    }
                    else
                    {
                        musicPlayer.player.enabled = value;//先激活再从指定时间播放
                        if (musicPlayer.isPlayAfterMusicOff)
                        {
                            musicPlayer.player.time = musicPlayer.stopAtTime;
                            musicPlayer.player.Play();
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// 创建一个音乐播放实例
    /// </summary>
    public static MusicPlayer NewInstance(string name = "")
    {
        string nameStr = "MusicPlayer";
        if (!string.IsNullOrEmpty(name)) nameStr += "_" + name;
        GameObject go = new GameObject(nameStr);
        DontDestroyOnLoad(go);
        MusicPlayer instance = go.AddComponent<MusicPlayer>();
        instance.player = go.AddComponent<AudioSource>();
        instance.player.playOnAwake = false;
        musicPlayers.Add(instance);
        return instance;
    }

    /// <summary>
    /// 读取或设置MusicPlayer播放的音频的音量
    /// </summary>
    public float Volume
    {
        get { if (player) return player.volume; return 1; }
        set { if (player) player.volume = value; }
    }

    public void Play(float delay, AudioClip[] clips, bool randomBegin = false, bool randomNext = false, float nextDelay = 1f)
    {
        if (currClips != null)
        {
            currClips = new AudioClip[1];
        }
        currClips = clips;
        currRandomBegin = randomBegin;
        currRandomNext = randomNext;
        currNextDelay = nextDelay;
        currClipIndex = currRandomBegin ? UnityEngine.Random.Range(0, currClips.Length) : 0;
        ExePlay(delay, currClips[currClipIndex], true, false);
    }

    public void Play(float delay, AudioClip clip, bool resume = true, bool loop = true)
    {
        currClips = null;
        ExePlay(delay, clip, resume, loop);
    }

    void ExePlay(float delay, AudioClip clip, bool resume, bool loop)
    {
        if (resume)
        {
            player.Stop();
        }
        if (player.clip != clip)
        {
            player.Stop();
            player.clip = clip;
            if (currClips != null && clip != null)
            {
                string timerId = "MusicPlayer_Timer";
                BTimer.Cancel(timerId);
                BTimer.Invoke(clip.length + currNextDelay, PlayNextMusic, timerId);
            }
        }
        player.loop = loop;
        if (IsMusicOn)
        {
            if (player.clip != null && !player.isPlaying)
            {
                player.PlayDelayed(delay);
            }
        }
        isPlayAfterMusicOff = true;
    }

    public void Stop()
    {
        if (player)
        {
            player.Stop();
        }
        isPlayAfterMusicOff = false;
    }

    public void Pause()
    {
        if (player && player.clip != null)
        {
            player.Pause();
        }
        isPlayAfterMusicOff = false;
    }

    public void Resume()
    {
        if (player && player.clip != null)
        {
            player.Play();
        }
        isPlayAfterMusicOff = true;
    }

    void PlayNextMusic()
    {
        if (currClips != null)
        {
            currClipIndex = currRandomNext ? UnityEngine.Random.Range(0, currClips.Length) : currClipIndex + 1;
            if (currClipIndex > currClips.Length - 1)
            {
                currClipIndex = 0;
            }
            ExePlay(0, currClips[currClipIndex], true, false);
        }
    }

    /// <summary>
    /// 音量慢慢淡出最后停止播放
    /// </summary>
    public void FadeOut(int duration)
    {
        if (player)
        {
            DOVirtual.Float(0, Volume, duration, (float v) =>
            {
                Volume = v;
            }).SetEase(Ease.Linear).OnComplete(Stop);
        }
    }

    /// <summary>
    /// 销毁对应的AudioSource对象
    /// </summary>
    public void Destroy()
    {
        try
        {
            Destroy(gameObject);
        }
        catch { }
    }
}